#1.加载数据集
import pandas as pd
import os

base_dir = os.path.dirname(os.path.abspath(__file__))
data_path = os.path.join(base_dir, "item6", "gender-data-y.txt")
print(f"数据文件路径: {data_path}")

names = ['age', 'height', 'weight', 'gender']
dataset = pd.read_csv(data_path, delimiter=',', names=names)
print(dataset.head()) 

from sklearn import preprocessing

#将身高何体重转换为浮点型
dataset['height']=dataset['height'].astype(float)
dataset['weight']=dataset['weight'].astype(float)

#将性别进行数值化处理
le =preprocessing.LabelEncoder()
dataset['label']=le.fit_transform(dataset['gender'])
print(dataset)




#2.数据集可视化
import matplotlib.pyplot as plt
data=dataset.iloc[range(0,100),range(1,3)].values	
target=dataset.iloc[range(0,100),range(4,5)].values.reshape(1,100)[0]

#绘制散点图
plt.scatter(data[target==0,0],data[target==0,1],s=60,c='r',marker='o') 
plt.scatter(data[target==1,0],data[target==1,1],s=60,c='g',marker='^')

plt.rcParams['font.sans-serif']='Simhei'
plt.xlabel('身高/cm')
plt.ylabel('体重/kg')
plt.show()




#3.寻找最佳深度值
from sklearn.model_selection import train_test_split
import numpy as np
from sklearn.tree import DecisionTreeClassifier
from sklearn.metrics import accuracy_score

#划分数据集
x,y=data,target
x_train,x_test,y_train,y_test=train_test_split(x,y,test_size=30,random_state=0)

#决策树深度与模型预测误差率计算
depth=np.arange(1,15)
err_list=[]

#开始遍历
for i in depth:
    model=DecisionTreeClassifier(criterion='entropy',max_depth=i)
    model.fit(x_train,y_train)
    pred=model.predict(x_test)
    ac=accuracy_score(y_test,pred)
    err=1-ac
    err_list.append(err)

#绘制决策树深度与模型预测误差率图形
plt.plot(depth,err_list,'ro-')
plt.rcParams['font.sans-serif']='Simhei'
plt.xlabel('决策树深度')
plt.ylabel('预测误差率')
plt.show()



#4.开始使用5或6作为模型开始训练
from sklearn.metrics import classification_report

#决策树深度取值为5时，训练模型
model=DecisionTreeClassifier(criterion='entropy',max_depth=5)
model.fit(x_train,y_train)

#对模型进行评估，并输出评估报告
pred=model.predict(x_test)
re=classification_report(y_test,pred)
print('模型评估报告：')
print(re)




#5.显示分类结果，并进行数据可视化
from matplotlib.colors import ListedColormap

#绘制分类界面
N,M=500,500		               
t1=np.linspace(140,195,N)                                      
t2=np.linspace(30,90,M)		          
x1,x2=np.meshgrid(t1,t2)		           
x_new=np.stack((x1.flat,x2.flat),axis=1)                    
y_predict=model.predict(x_new)	                         
y_hat=y_predict.reshape(x1.shape)	          
iris_cmap=ListedColormap(["#ACC6C0","#FF8080"])
plt.pcolormesh(x1,x2,y_hat,cmap=iris_cmap)	

#绘制两个类别的样本数据点
plt.scatter(x[y==0,0],x[y==0,1],s=60,c='r',marker='o')			                                #绘制标签为0的样本点
plt.scatter(x[y==1,0],x[y==1,1],s=60,c='g',marker='^')	

#设置坐标轴的名称并显示图形
plt.rcParams['font.sans-serif']='Simhei'
plt.xlabel('身高/cm')
plt.ylabel('体重/kg')
plt.show()